package org.ainlolcat.ainscience.statistics.handlers.fitting;

import org.ainlolcat.ainscience.utils.ArraysUtil;
import org.ainlolcat.ainscience.statistics.handlers.fitting.functions.ZeroBasedGaussFunction;
import org.ainlolcat.ainscience.statistics.handlers.fitting.functions.ZeroBasedPsdVoigtFunction;
import org.apache.commons.math.optimization.fitting.CurveFitter;
import org.apache.commons.math.optimization.fitting.ParametricRealFunction;
import org.apache.commons.math.optimization.general.LevenbergMarquardtOptimizer;
import org.apache.log4j.Logger;

/**
* @author ainlolcat
*         Date: 5/9/13
*/
public class ZeroBasedPsvVoigtPeakFitting extends AbstractPeakFitting{
    private static Logger log = Logger.getLogger(ZeroBasedPsvVoigtPeakFitting.class);

    public ZeroBasedPsvVoigtPeakFitting(PeakFittingStatisticHandler peakFittingStatisticHandler) {
        super(peakFittingStatisticHandler);
        function = new ZeroBasedPsdVoigtFunction();
    }

    protected double[] prepareGraph(double[] x, double[] y){
        int baseLineDots = peakFittingStatisticHandler.baseline;
        if (baseLineDots > x.length/6){
            baseLineDots = x.length/6;
        }
        maximum = y[0];
        mean = x[0];
        double ySumm = 0;
        double y0 = 0,x0 = 0,y1 = 0,x1 = 0;
        for (int i=0;i<baseLineDots;i++){
            x0+=x[i];
            y0+=y[i];
            x1+=x[x.length-1-i];
            y1+=y[y.length-1-i];
        }
        x0 = x0/baseLineDots;
        y0 = y0/baseLineDots;
        x1 = x1/baseLineDots;
        y1 = y1/baseLineDots;
        double k = (y1-y0)/(x1-x0);
        double[] out = new double[x.length<y.length?x.length:y.length];
        for (int i=0;i<(x.length<y.length?x.length:y.length);i++){
            out[i] = (y[i] - (y0 + k * (x[i] - x0)));
        }
        for (int i=0;i<(x.length<y.length?x.length:y.length);i++){
            maximum = y[i]>maximum?y[i]:maximum;
            ySumm+=y[i];
            mean += y[i]*x[i];
            disp += y[i]*x[i]*x[i];
        }
        mean = mean / ySumm;
        disp = disp / ySumm - mean * mean;
        for (int i=0;i<(x.length<y.length?x.length:y.length);i++){
            out[i] = out[i]/maximum;
        }
        return out;
    }
}
